from PyQt4 import QtNetwork 
from PyQt4 import QtCore
from PyQt4 import QtNetwork
from PyQt4 import QtGui

import wmi

class ClientProcess(QtCore.QObject):
    def __init__(self, hostAddress, refreshTime, portNumber=23, parent=None):
        QtCore.QObject.__init__(self, parent)
        assert isinstance ( refreshTime, WindowsService);
        
        self.hostAddress = hostAddress
        self.portAddress = portNumber
        self.refreshTime = refreshTime
        
        self.OP_GETPROCESSLIST = 0
        self.OP_KILLANYPROCESS = 1
        
        self.timer = QtCore.QTimer()
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.sendData)
        self.timer.start(self.refreshTime);

        self.tcpSocket = QtNetwork.QTcpSocket(self)
    
        self.connect(self.tcpSocket, QtCore.SIGNAL("readyRead()"), self.readyRead)
        self.connect(self.tcpSocket, QtCore.SIGNAL("error(QAbstractSocket::SocketError)"), self.displayError)
        self.connect(self.tcpSocket, QtCore.SIGNAL("disconnected()"), self.disconnectedFromHost)
        self.connect(self.tcpSocket, QtCore.SIGNAL("connected()"), self.connectedToHost)
                     
    def readyRead(self):
        print "We are ready for read"
        instr = QtCore.QDataStream(self.tcpSocket)
        instr.setVersion(QtCore.QDataStream.Qt_4_0)
        #llegim el tamany de les dades a capturar.
        dataSize = QtCore.QString(self.tcpSocket.bytesAvailable())
        if not( self.tcpSocket.bytesAvailable() >= 2 ):
             return 
        else:
            operationvalue = instr.readUInt16()
        
        procName = QtCore.QString()
        if operationvalue == self.OP_KILLANYPROCESS:
            instr >> procName
            print QtCore.QString("Kill process").append(procName)
        
            
            c = wmi.WMI()
            procList = [proc for proc in  c.Win32_Process () ]

            for process in procList:
                if ( process.Caption.lower() == procName ):
                    process.Terminate()
                
        """Build a connection string from a dictionary of parameters.
    Returns string."""

    def displayError(self, socketError):
        if socketError ==  QtNetwork.QAbstractSocket.RemoteHostClosedError:
            pass
        elif socketError ==  QtNetwork.QAbstractSocket.HostNotFoundError:
            print (self.tr(
                      "The host was not found. Please check the "
                      "host name and port settings."))
        elif socketError ==  QtNetwork.QAbstractSocket.ConnectionRefusedError:
            print (self.tr(
                      "The connection was refused by the peer. "
                      "Make sure the server is running,\n"
                      "and check that the host name and port "
                      "settings are correct."))
        else:
            print (self.tr("The following error occurred: %1.")
                  .arg(self.tcpSocket.errorString()))
        
    def sendData(self):
         
            self.tcpSocket.connectToHost(QtNetwork.QHostAddress(self.hostAddress), self.portAddress)
            """ Esperem a estar connectats i consultem la llista de processos a enviar. """
            if self.tcpSocket.waitForConnected(1000):
                block = QtCore.QByteArray()
                out = QtCore.QDataStream(block, QtCore.QIODevice.WriteOnly)
                out.setVersion(QtCore.QDataStream.Qt_4_0)
                out.writeUInt16(self.OP_GETPROCESSLIST)
                self.sendProcessList ( out )
                out.device().seek(0)
                
                self.tcpSocket.write(block)

    def sendProcessList(self, dataStream):
        c = wmi.WMI()
        procList = [proc for proc in  c.Win32_Process () ]
        dataStream.writeUInt16(len(procList))

        for process in procList:
            #print process.Caption
            dataStream << QtCore.QString(process.Caption.lower())
            #process.Terminate()
                
    def disconnectedFromHost(self):
        print "The host disconnects"
        
    def connectedToHost(self):
        print "The host is connected"
